package config

import (
	"strings"
)

// Configuration 整个配置文件的表示，包含多个section
type Configuration struct {
	sections []*Section
}

// Sections 返回conf内部的多个secdtions
func (conf *Configuration) Sections() []*Section {
	return conf.sections
}

// GetSection 根据 section name 获取section
func (conf *Configuration) GetSection(secname string) (*Section, error) {
	if strings.Trim(secname, " ") == "" {
		return nil, ErrorFooEmptyString
	}
	for _, section := range conf.sections {
		if section.Name() == secname {
			return section, nil
		}
	}
	return nil, ErrorFooNoItem
}

// AddSection 增加一个名为secname的section，键值对由kvstrs给出，kvstr形式为 " = "
// func (conf *Configuration) AddSection(secname string, kvstrs []string) error {
// 	if strings.Trim(secname, " ") == "" || len(kvstrs) == 0 {
// 		return ErrorFooEmptyString
// 	}
// 	section, err := NewSection(secname, kvstrs)
// 	if err != nil {
// 		return err
// 	}
// 	conf.Sections = append(conf.Sections, section)
// 	return nil
// }

// ConfigurationCmp 比较两个conf的区别，并将区别返回
// 注意，返回的时候，应该构造diff数组，每两个代表一次区别
// 0/2/4.. 代表conf1的选项
// 1/3/5...代表conf2的选项
// diff[0] = Section("default").Key("name").Val("kaijie")
// diff[1] = nil or Section("default").Key("name").Val("xxxxxx")
// func ConfigurationCmp(conf1 *Configuration, conf2 *Configuration) (bool, []*Section) {
// 	if conf1 == nil || conf2 == nil {
// 		return false, nil
// 	}

// }

// NewConfiguration 根据传入的文件经过parse之后生成对应的选项结构
func NewConfiguration(fileName string) (*Configuration, error) {
	// 首先经过parse，如果parse失败，代表格式不符合规范
	rawSecs, err := Parse(fileName)
	if err != nil {
		return nil, err
	}
	conf := new(Configuration)
	// 如果经过了parse，parse将会将每个section都以name+[]string的形式返回
	for _, rawSec := range rawSecs {
		section, err := NewSection(rawSec.Name(), rawSec.KvStrings())
		if err != nil {
			return nil, err
		}
		conf.sections = append(conf.sections, section)
	}
	// 通过parse的返回来构建configuration
	return conf, nil
}
